import {Attrs, CaluType, ColorStr, MaterialInfo, MixRet} from "../type/Type";
import {ConfigKey} from "../constant/ConfigConstant";
import {
    AttributeEnum,
    MaterialData,
    PlayerAttribute,
    PositionType,
    TaskType,
    UnitAttribute
} from "../frame/dataSource/DataModel";
import Configer from "../frame/apiModel/config/Configer";
import MathUtil from "../frame/codeAdapter/MathUtil";
import {FinalKey} from "../constant/FinalConstant";
import {Logger} from "../frame/apiModel/config/Logger";
import {CodeUtil} from "../frame/codeAdapter/CodeUtil";
import {UnitModel} from "../frame/apiModel/adapterModel/model3/UnitModel";
import {ItemJson} from "../frame/apiModel/model/StoreJson";
import {PlayerFactory} from "../frame/PlayerFactory";
import {ItemModel} from "../frame/apiModel/adapterModel/model3/ItemModel";
import {PlayerModel} from "../frame/apiModel/adapterModel/model4/PlayerModel";
import {ModelFactory} from "../frame/apiModel/adapterModel/model5/ModelFactory";
import {ItemDataKey, PlayerDataKey} from "../frame/dataSource/DataSource";
import {DataRouterUtil} from "./router/DataRouterUtil";
import { PositionConfig, UIConfigKey } from "../constant/UIConfig";

export class Util {
    static sumUnitAttribute (attr1: UnitAttribute, attr2: UnitAttribute, sumType: CaluType): UnitAttribute {
        const newAttr = new UnitAttribute();
        if (attr1) {
            const keys  = Object.keys(attr1);
            for (let i = 0; i < keys.length; i ++) {
                const key = keys[i]
                let addValue = 0;
                if (attr2 && !CodeUtil.isNullOrZero(attr2[key])) {
                    addValue = attr2[key]
                }
                let oldValue = 0;
                if (attr1 && !CodeUtil.isNullOrZero(attr1[key])) {
                    oldValue = attr1[key];
                }
                if (sumType === CaluType.add) {
                    newAttr[key] = oldValue + addValue;
                } else if (sumType === CaluType.sub) {
                    newAttr[key] = oldValue - addValue;
                }
            }
        } else {
            Logger.toastError('属性计算时attr1为空');
        }
        return newAttr;
    }
    static sumPlayerAttribute (attr1: PlayerAttribute, attr2: PlayerAttribute, sumType: CaluType): PlayerAttribute {
        const newAttr = new PlayerAttribute();
        if (attr1) {
            const keys  = Object.keys(attr1);
            for (let i = 0; i < keys.length; i ++) {
                const key = keys[i]
                let addValue = 0;
                if (attr2 && !CodeUtil.isNullOrZero(attr2[key])) {
                    addValue = attr2[key]
                }
                let oldValue = 0;
                if (attr1 && !CodeUtil.isNullOrZero(attr1[key])) {
                    oldValue = attr1[key];
                }
                if (sumType === CaluType.add) {
                    newAttr[key] = oldValue + addValue;
                } else if (sumType === CaluType.sub) {
                    newAttr[key] = oldValue - addValue;
                }
            }
        } else {
            Logger.toastError('属性计算时attr1为空');
        }
        return newAttr;
    }
    static sumAttributes (attr1: Attrs, attr2: Attrs, sumType: CaluType): Attrs {
        let retUnitAttr, retPlayerAttr;

        let unitAttr1 = attr1.unitAttr;
        let playerAttr1 = attr1.playerAttr;

        const unitAttr2 = attr2?.unitAttr;
        const playerAttr2 = attr2?.playerAttr;

        if (unitAttr1 && unitAttr2) {
            retUnitAttr = Util.sumUnitAttribute(unitAttr1, unitAttr2, sumType);
        } else if (unitAttr1) {
            retUnitAttr = Util.cloneAttr(unitAttr1);
        } else if (unitAttr2) {
            retUnitAttr = Util.cloneAttr(unitAttr2);
        }

        if (playerAttr1 && playerAttr2) {
            retPlayerAttr = Util.sumPlayerAttribute(playerAttr1, playerAttr2, sumType);
        } else if (playerAttr1) {
            retPlayerAttr = Util.cloneAttr(playerAttr1);
        } else if (playerAttr2) {
            retPlayerAttr = Util.cloneAttr(playerAttr2);
        }

        return { unitAttr: retUnitAttr, playerAttr: retPlayerAttr }
    }

    // 通过将属性设置进attribute中的办法设置单位的属性
    static setTargetAttributeEnumToHeroByAttribute(targetUnit: UnitModel, targetAttr: AttributeEnum, resultAttr: UnitAttribute, newValue: number) : UnitAttribute {
        const targetAttrStr = AttributeEnum[targetAttr];
        switch (targetAttr) {
            default: {
                if (targetAttr) {
                    if (resultAttr[targetAttr]) {
                        resultAttr[targetAttr] = newValue;
                    }
                } else {
                    return resultAttr;
                }
                break;
            }
        }
        return resultAttr;
    }
    static getTargetAttributeEnumByHero(targetAttr: AttributeEnum, currentAttr: UnitAttribute, unit: UnitModel) : number {
        let sum = 0;
        switch (targetAttr) {
            case AttributeEnum.coin:{
                const player = PlayerFactory.getInstance().getUnitOwner(unit);
                sum = player.gold;
                break;
            }
            case AttributeEnum.wood:{
                const player = PlayerFactory.getInstance().getUnitOwner(unit);
                sum = player.lumber;
                break;
            }
            case AttributeEnum.exp:{
                sum = unit.experience;
                break;
            }
            default : {
                if (targetAttr && currentAttr[targetAttr]) {
                    sum = currentAttr[targetAttr];
                } else {
                    return 0;
                }
                break;
            }
        }
        return sum
    }
    static getTargetAttributeEnumByPlayer(targetAttr: AttributeEnum, currentAttr: PlayerAttribute) : number {
        let sum = 0;
        switch (targetAttr) {
            default : {
                if (targetAttr) {
                    sum = currentAttr[targetAttr];
                } else {
                    return 0;
                }
                break;
            }
        }
        return sum
    }
    static getTargetAttributeEnumByNotHero(targetUnit: UnitModel, targetAttr: AttributeEnum, includeBonuses: boolean = true) : number {
        let sum = 0;
        if (targetUnit) {
        } else {
            return;
        }
        switch (targetAttr) {
            case AttributeEnum.strength: {
                if (targetUnit.isHero()) {
                    sum = targetUnit.getStrength(includeBonuses);
                } else {
                    sum = 0;
                }
                break;
            }
            case AttributeEnum.agile: {
                if (targetUnit.isHero()) {
                    sum = targetUnit.getAgility(includeBonuses);
                } else {
                    sum = 0;
                }
                break;
            }
            case AttributeEnum.intellect: {
                if (targetUnit.isHero()) {
                    sum = targetUnit.getIntelligence(includeBonuses);
                } else {
                    sum = 0;
                }
                break;
            }
            case AttributeEnum.life: {
                sum = targetUnit.life;
                break;
            }
            case AttributeEnum.maxLife: {
                sum = targetUnit.maxLife;
                break;
            }
            case AttributeEnum.magic: {
                sum = targetUnit.mana;
                break;
            }
            case AttributeEnum.maxMagic: {
                sum = targetUnit.maxMana;
                break;
            }
            // case AttributeEnum.defense: {
            //     sum = targetUnit.defense;
            //     break;
            // }
            // case AttributeEnum.attack: {
            //     sum = targetUnit.attack;
            //     break;
            // }
            case AttributeEnum.attackSpeed: {
                sum = targetUnit.attackSpeed;
                break;
            }
            case AttributeEnum.speed: {
                sum = targetUnit.moveSpeed;
                break;
            }
            case AttributeEnum.coin: {
                const player = PlayerFactory.getInstance().getUnitOwner(targetUnit)
                sum = player.gold
                break;
            }
            case AttributeEnum.wood: {
                const player = PlayerFactory.getInstance().getUnitOwner(targetUnit)
                sum = player.lumber
                break;
            }
            case AttributeEnum.exp: {
                if (targetUnit.isHero()) {
                    sum = targetUnit.experience;
                } else {
                    sum = 0;
                }
                break;
            }
            case AttributeEnum.attackDistance: {
                sum = targetUnit.attackDistance;
                break;
            }
            case AttributeEnum.attackSpeedInterval: {
                sum = targetUnit.attackSpeedInterval;
                break;
            }
            // 其他属性无法直接获取，请访问UnitController获取
            // 在TriggerUtil中这个方法仅作为获取非玩家单位属性使用，这时特殊属性为0
            default: {
                break;
            }
        }
        if (sum) {
            sum = Util.extraAdapt(sum, targetAttr, true);
            return sum
        }
        return 0;
    }
    static getStoreKey(name: string, value: string) {
        const split = Configer.getConfig(ConfigKey.storeSplit);
        return `${name}${split}${value}`
    }
    static mapUnitArr(arr: UnitModel[], callBack: (unit: UnitModel) => void) {
        for (let i = 0; i < arr.length; i ++) {
            const unit = arr[i];
            callBack(unit);
        }
    }
    static setTargetAttributeEnumToNotHero(targetUnit: UnitModel, targetAttr: AttributeEnum, newValue: number, bExtra?: boolean) {
        newValue = Util.extraAdapt(newValue, targetAttr);
        const attrStr = AttributeEnum[targetAttr];
        // Util.loggerInDev(`设置属性:${attrStr} 为:${newValue}`, LogType.attrDev);
        if (targetUnit) {
        } else {
            return;
        }
        switch (targetAttr) {
            case AttributeEnum.agile: {
                if (targetUnit.isHero()) {
                    if (bExtra) {
                        targetUnit.setExtraAttr(newValue, targetAttr);
                    } else {
                        targetUnit.setAgility(newValue, true)
                    }
                }
                break;
            }
            case AttributeEnum.strength: {
                if (targetUnit.isHero()) {
                    if (bExtra) {
                        targetUnit.setExtraAttr(newValue, targetAttr);
                    } else {
                        targetUnit.setStrength(newValue, true)
                    }
                }
                break;
            }
            case AttributeEnum.intellect: {
                if (targetUnit.isHero()) {
                    if (bExtra) {
                        targetUnit.setExtraAttr(newValue, targetAttr);
                    } else {
                        targetUnit.setIntelligence(newValue, true)
                    }
                }
                break;
            }
            // case AttributeEnum.attack: {
            //     if (bExtra) {
            //         targetUnit.setExtraAttr(newValue, targetAttr);
            //     } else {
            //         targetUnit.attack = newValue;
            //     }
            //     break;
            // }
            // case AttributeEnum.defense: {
            //     if (bExtra) {
            //         targetUnit.setExtraAttr(newValue, targetAttr);
            //     } else {
            //         targetUnit.defense = newValue;
            //     }
            //     break;
            // }
            case AttributeEnum.lifeRecovery: {
                if (bExtra) {
                    targetUnit.setExtraAttr(newValue, targetAttr);
                } else {
                    // todo 恢复现在只能通过额外属性的方式增加
                    // targetUnit.defense = newValue;
                    // SetUnitState(targetUnit, ConvertUnitState(0x20), newValue);
                }
                break;
            }
            case AttributeEnum.magicRecovery: {
                if (bExtra) {
                    targetUnit.setExtraAttr(newValue, targetAttr);
                } else {
                    // todo 恢复现在只能通过额外属性的方式增加
                    // targetUnit.defense = newValue;
                    // SetUnitState(targetUnit, ConvertUnitState(0x20), newValue);
                }
                break;
            }
            case AttributeEnum.speed: {
                if (bExtra) {
                    targetUnit.setExtraAttr(newValue, targetAttr);
                } else {
                    targetUnit.moveSpeed = newValue;
                }
                break;
            }
            case AttributeEnum.attackSpeed: {
                if (bExtra) {
                    targetUnit.setExtraAttr(newValue, targetAttr);
                } else {
                    targetUnit.attackSpeed = newValue;
                }
                break;
            }
            case AttributeEnum.maxLife: {
                targetUnit.maxLife = newValue;
                break;
            }
            case AttributeEnum.maxMagic: {
                targetUnit.maxMana = newValue;
                break;
            }
            case AttributeEnum.life: {
                targetUnit.life = newValue;
                break;
            }
            case AttributeEnum.magic: {
                targetUnit.mana = newValue;
                break;
            }
            case AttributeEnum.coin: {
                const player = PlayerFactory.getInstance().getUnitOwner(targetUnit);
                player.gold = newValue;
                break;
            }
            case AttributeEnum.wood: {
                const player = PlayerFactory.getInstance().getUnitOwner(targetUnit);
                player.lumber = newValue;
                break;
            }
            case AttributeEnum.exp: {
                if (targetUnit.isHero()) {
                    targetUnit.setExperience(newValue)
                }
                break;
            }
            case AttributeEnum.attackDistance: {
                targetUnit.attackDistance = newValue
                break
            }
            case AttributeEnum.size: {
                const sizeValue = 1 + newValue;
                targetUnit.setScale(sizeValue, sizeValue, sizeValue)
                break
            }
            case AttributeEnum.attackSpeedInterval: {
                targetUnit.attackSpeedInterval = newValue
                break
            }
            // case AttributeEnum.expAddRadix: {
            //     const radix = newValue + 100;
            //     const player = GetOwningPlayer(targetUnit);
            //     SetPlayerHandicapXPBJ(player, radix);
            //     break;
            // }
            // 暴击相关与回复效果  普通单位无法修改
            default: {
                break;
            }
        }
    }
    // 属性适配方法  因为像攻击速度 魔法回复这种属性在魔兽中是以小数形式存在，并不容易观看，通过这个方法将其转换成百分数
    static extraAdapt (oldValue: number, targetAttr: AttributeEnum, toAttr: boolean = false) {
        let newValue = oldValue;
        switch (targetAttr) {
            case AttributeEnum.lifeRecovery: {
                if (toAttr) {
                    newValue = newValue / 100;
                } else {
                    newValue = newValue * 100;
                }
                break;
            }
            // case AttributeEnum.size: {
            //     if (toAttr) {
            //         newValue = newValue * 100;
            //     } else {
            //         newValue = newValue / 100;
            //     }
            //     break;
            // }
            case AttributeEnum.magicRecovery:
            case AttributeEnum.attackSpeed: {
                if (toAttr) {
                    newValue = newValue * 100;
                } else {
                    newValue = newValue / 100;
                }
                break;
            }
        }
        return newValue;
    }

    static attackAdapt (unit: UnitModel, mainAttr: string, targetAttr: UnitAttribute, extraAttr: UnitAttribute) {
        // 魔兽中获取攻击力的接口只能获取白字攻击力，要想获取角色当前正确的攻击力需要加上框架所增加的攻击力
        // 取原值时会用白字攻击力减去一个绿字攻击  是不应该减的  在这里补回来
        // const attack = targetAttr[AttributeEnum.attack];
        // const extraAttack = extraAttr[AttributeEnum.attack];
        // targetAttr[AttributeEnum.attack] = attack + extraAttack;
        // Util.loggerInDev(`矫正前攻击力：${targetAttr[AttributeEnum.attack]}`, LogType.attrDev);
        // let whiteMainAttr, greenMainAttr;
        // switch (mainAttr) {
        //     case MainAttr.AGI:{
        //         whiteMainAttr = Util.getTargetAttributeEnumByNotHero(unit, AttributeEnum.agile, false);
        //         greenMainAttr = Util.getTargetAttributeEnumByNotHero(unit, AttributeEnum.agile, true);
        //         break;
        //     }
        //     case MainAttr.STR:{
        //         whiteMainAttr = Util.getTargetAttributeEnumByNotHero(unit, AttributeEnum.strength, false);
        //         greenMainAttr = Util.getTargetAttributeEnumByNotHero(unit, AttributeEnum.strength, true);
        //         break;
        //     }
        //     case MainAttr.INT:{
        //         whiteMainAttr = Util.getTargetAttributeEnumByNotHero(unit, AttributeEnum.intellect, false);
        //         greenMainAttr = Util.getTargetAttributeEnumByNotHero(unit, AttributeEnum.intellect, true);
        //         break;
        //     }
        // }
        // Util.loggerInDev(`白字主属性：${whiteMainAttr}`, LogType.attrDev);
        // Util.loggerInDev(`绿字主属性：${greenMainAttr}`, LogType.attrDev);
        // let offset = 0;
        // if (greenMainAttr && whiteMainAttr) {
        //     offset = greenMainAttr - whiteMainAttr;
        // }
        // targetAttr[AttributeEnum.attack] = attack - offset + extraAttack;
        // Util.loggerInDev(`主属性提供的攻击力：${offset}`, LogType.attrDev);
        // Util.loggerInDev(`框架增加的额外攻击力：${extraAttack}`, LogType.attrDev);
        // Util.loggerInDev(`攻击力原值：${targetAttr[AttributeEnum.attack]}`, LogType.attrDev);
    }

    static doAllFuns(funs: (() => void)[]) {
        funs.map(
            (value, index, array) => {
                value();
            }
        )
    }
    static equalTime(time1: number, time2: number) {
        const date1 = new Date(time1);
        const date2 = new Date(time2);
        const year1 = date1.getFullYear();
        const year2 = date2.getFullYear();
        if (year1 === year2) {
        } else {
            return false;
        }
        const month1 = date1.getMonth();
        const month2 = date2.getMonth();
        if (month1 === month2) {
        } else {
            return false;
        }
        const day1 = date1.getDate();
        const day2 = date2.getDate();
        if (day1 === day2) {
        } else {
            return false;
        }
        return  true;
    }
    static getNameByPosition(position: PositionType) {
        let positionStr = '未知';
        const equipAdapts = Configer.getUIConfig(UIConfigKey.EquipAdapt) as PositionConfig[];
        const maxGoodsEquipNum = Configer.getConfig(ConfigKey.maxGoodsEquipNum) as number;

        for (let i = 0; i < maxGoodsEquipNum; i++) {
            const equipAdapt = equipAdapts[i];
            if (!CodeUtil.isNullOrZero(equipAdapt)) {
                if (equipAdapt.position === position) {
                    return equipAdapt.name;
                }
            }
        }
        return positionStr;
    }

    static getStrByTaskType(taskType: TaskType) {
        switch (taskType) {
            case TaskType.main:
                return '主线任务';
            case TaskType.deputy:
                return '支线任务';
            case TaskType.circulate:
                return '循环任务';
            case TaskType.forever:
                return '成就任务';
            case TaskType.team:
                return '团队任务';
        }
    }
    static cloneAttr(attr: UnitAttribute) {
        const newAttr = new UnitAttribute();
        const keys = Object.keys(attr);
        for (let i = 0; i < keys.length; i ++) {
            const key = keys[i];
            const value = attr[key];
            // Util.loggerInDev(`key:${AttributeEnum[key]}------value:${value}`, LogType.error)
            newAttr[key] = value;
        }
        return newAttr;
    }
    static formatTimeFormSecond (second: number): string {
        if (second === 0) {
            return '00:00'
        }
        const tempSecond= second % 60;
        const minute = MathUtil.floor(second / 60);
        const tempMinute = minute % 60;
        // const hour = minute / 60;
        // const tempHour = hour % 24;
        let secondStr = `${tempSecond}`;
        if (tempSecond < 10) {
            secondStr = `0${tempSecond}`;
        }
        let minuteStr = `${tempMinute}`;
        if (tempMinute < 10) {
            minuteStr = `0${tempMinute}`;
        }
        return `${minuteStr}:${secondStr}`
    }
    static formatFormNumber (number: number): string {
        if (number === 0) {
            return '0'
        }
        // 亿
        const  hundredMillion = number / 100000000
        // 万
        const  tenThousand = number / 10000
        // 千
        const  thousand = number / 1000
        const saveFloat = 1;
        if (hundredMillion >= 1) {
            const str = `${number}`;
            const len = str.length;
            const l = len - 8;
            const int = str.slice(0, l);
            const float = str.slice(l, l + saveFloat);
            return `${int}.${float}y`
        }
        if (tenThousand >= 1) {
            const str = `${number}`;
            const len = str.length;
            const l = len - 4;
            const int = str.slice(0, l);
            const float = str.slice(l, l + saveFloat);
            return `${int}.${float}w`
        }
        if (thousand >= 1) {
            const str = `${number}`;
            const len = str.length;
            const l = len - 3;
            const int = str.slice(0, l);
            const float = str.slice(l, l + saveFloat);
            return `${int}.${float}k`
        }
        return `${number}`
    }
    static checkToMixByMixDatas(materialInfos: MaterialInfo[], materialDatas: MaterialData[], bStop: boolean = true) {
        // const checkMixRets: { mixId: string, funs: (() => void)[] }[] = [];
        const checkMixRets: { [mixId: string]: MixRet } = {};
        if (materialDatas && materialDatas.length > 0) {
            const arrs: {id: string, items: string[], nums: string[]}[] = [];
            // 预先装载所有合成表信息
            for (let i = 0; i < materialDatas.length; i++) {
                const mixData = materialDatas[i];
                const id = mixData.id;
                const itemStrs = mixData.material_id;
                let itemArr = CodeUtil.getArrBySplit(itemStrs);

                const numStrs = mixData.material_num;
                const numArr = CodeUtil.getArrBySplit(numStrs);
                const element = { id, items: itemArr, nums: numArr };
                arrs.push(element);
            }

            const funMap: { [mixId: string]: (() => void)[] } = {};

            // 遍历当前物品组，判断物品组中物品是否符合合成条件
            for (let itemIndex = 0; itemIndex < materialInfos.length; itemIndex++) {
                const materialInfo = materialInfos[itemIndex];
                const currentId = materialInfo.id;
                const currentNum = materialInfo.num;
                const deleteFun = materialInfo.deleteFun;
                const changeNumFun = materialInfo.changeNumFun;
                for (let materialIndex = 0; materialIndex < arrs.length; materialIndex++) {
                    const data = arrs[materialIndex];
                    const mixId = data.id;
                    const items = data.items;
                    const nums = data.nums;

                    const index = items.indexOf(currentId);
                    if (index >= 0) {
                        const itemStrNum = nums[index];
                        const itemNum = MathUtil.toNumber(itemStrNum);
                        let fun;

                        if (currentNum > itemNum) {
                            Logger.toastMix(`合成表中有此物品，并且数量比需要的更多`);
                            const newNum = currentNum - itemNum;
                            items.splice(index, 1)
                            nums.splice(index, 1);
                            if (changeNumFun) {
                                fun = () => {
                                    changeNumFun(newNum);
                                }
                            }
                        } else if (currentNum === itemNum) {
                            Logger.toastMix(`合成表中有此物品，并且数量和需要一样多`);
                            items.splice(index, 1)
                            nums.splice(index, 1)
                            if (deleteFun) {
                                fun = () => {
                                    deleteFun();
                                }
                            }
                        } else {
                            Logger.toastMix(`合成表中有此物品${currentId}，但数量不足: 需要${itemNum}，却只有${currentNum}`);
                        }

                        if (fun) {
                            const funs = funMap[mixId];
                            if (funs) {
                                funs.push(fun);
                            } else {
                                funMap[mixId] = [fun]
                            }
                        }

                        const len = items.length;
                        if (len === 0) {
                            const checkMixRet: MixRet = { mixId: mixId, funs: funMap[mixId] };
                            checkMixRets[mixId] = checkMixRet;
                            if (bStop) {
                                break;
                            }
                        }
                    }
                }
                const keys = Object.keys(checkMixRets);
                if (bStop && keys.length > 0) {
                    break;
                }
            }
        }
        return checkMixRets;
    }

    static getColorStr(color: ColorStr, text: string) {
        return `${color}${text}|r`
    }
    static checkInSplit(str: string, ele: string) {
        const arr = CodeUtil.getArrBySplit(str);
        for (let i = 0; i < arr.length; i++) {
            const temp = arr[i];
            if (temp === ele) {
                return i;
            }
        }
        return -1;
    }
    static checkIsOneDay(time1: number, time2: number) {
        const hours1 = time1 / (24 * 3600);
        const hours2 = time2 / (24 * 3600);
        if ((hours1 - hours2) > 0 || (hours2 - hours1) > 0) {
            return false;
        }
        return true;
    }
    static getAllBattlePetAndSummoned(player: PlayerModel) {
        const unitArr: UnitModel[] = [];
        const summoneds: UnitModel[] = player.data[PlayerDataKey.summoned];
        for (let i = 0; i < summoneds.length; i++) {
            const summoned = summoneds[i];
            if (summoned?.isAliveInBattle()) {
                unitArr.push(summoned);
            }
        }
        const pets: UnitModel[] = player.data[PlayerDataKey.pet];
        const petsNum = Configer.getConfig(ConfigKey.maxPetNum)
        for (let i = 0; i < petsNum; i++) {
            const pet = pets[i];
            if (pet?.isAliveInBattle()) {
                const visible = pet.show;
                if (visible) {
                    unitArr.push(pet);
                }
            }
        }
        return unitArr;
    }

    /**
     * sourceAttr 计算的原值 使用百分比时 使用这个属性计算
     * originallyAttribute 修改的原值 计算后的修改值在这个属性的基础上变化
     * bAlways属性用来标记是使用属性系统计算他的属性还是直接修改他的属性
     * bForce为ture将允许将resultAttribute减为负数
     * 造成伤害时 百分比需要是0  因为计算伤害值时已经计算过百分比了
     */
    static caluAbilityAttr(targetUnit: UnitModel, activePlayer: PlayerModel, sourceAttribute: UnitAttribute, originallyAttribute: UnitAttribute, resultAttribute: UnitAttribute, targetAttr: AttributeEnum, sourceAttr: AttributeEnum, value: number, percentage: number, caluType: CaluType, bForce: boolean, bAlways: boolean, effectId: string) {
        if (AttributeEnum[targetAttr]) {
        } else {
            Logger.toastError(`技能效果: ${effectId}, 暂时不支持对${targetAttr}的修改`)
            return;
        }
        let sum, newValue = value;
        Logger.toastSkill(`增益值: ${newValue}`)
        if (bAlways) {
            sum = Util.getTargetAttributeEnumByHero(targetAttr, originallyAttribute, targetUnit);
        } else {
            sum = Util.getTargetAttributeEnumByHero(targetAttr, resultAttribute, targetUnit);
        }
        if (sourceAttr && !CodeUtil.isNullOrZero(percentage)) {
            const tempSum = Util.getTargetAttributeEnumByHero(sourceAttr, sourceAttribute, targetUnit);
            Logger.toastSkill(`源属性-${AttributeEnum[sourceAttr]}: ${tempSum}`)
            const percentageNum = newValue / 100;
            newValue = tempSum * percentageNum;
        }
        if (sum && targetAttr) {
            Logger.toastSkill(`目标属性-${AttributeEnum[targetAttr]}: ${sum}`)
        }
        if (newValue && targetAttr) {
            Logger.toastSkill(`计算值-${AttributeEnum[targetAttr]}: ${newValue}`)
        }

        if (caluType === CaluType.sub) {
            if (sum < newValue && !bForce) {
                return false;
            }
            newValue = sum - newValue;
        } else if (caluType === CaluType.add) {
            newValue = sum + newValue;
        } else if (caluType === CaluType.set) {
        }
        Logger.toastSkill(`修改值为${newValue}`)
        Logger.toastSkill(`修改目标属性：${AttributeEnum[targetAttr]}`)
        if (bAlways) {
            Util.setTargetAttributeEnumToNotHero(targetUnit, targetAttr, newValue);
            Logger.toastSkill(`永久修改白字`)
        } else {
            Util.setTargetAttributeEnumToHeroByAttribute(targetUnit, targetAttr, resultAttribute, newValue);
            Logger.toastSkill(`暂时修改绿字`)
        }
        return true;
    }

}